import type { RouteRecordRaw } from "vue-router";
import router, { constantRoutes } from "@/router";
import MenuAPI, { type RouteVO } from "@/api/menu";

const modules = import.meta.glob('@/views/**/**.vue');
export const Layout = () => import('@/layout/index.vue');

export const useMenuStore = defineStore("menu", () => {
  const menuRoutes = ref<RouteRecordRaw[]>([]);//菜单路由列表
  const loadRoutesFlag = ref(false);//true，已加载动态路由；false，未加载

  /* 生成路由 */
  function generateRoutes() {
    return new Promise<RouteRecordRaw[]>((resolve, reject) => {
      MenuAPI.getRoutes()
        .then((res) => {
          // 转换路由数据为组件
          const dynamicRoutes = transformRoutes(res.data);
          // 设置菜单路由列表
          menuRoutes.value = constantRoutes.concat(dynamicRoutes);
          // 避免重复加载路由
          loadRoutesFlag.value = true;
          resolve(dynamicRoutes);
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  /* 重置路由 */
  const resetRouter = () => {
    // 遍历菜单中的路由，保留静态路由
    menuRoutes.value.forEach((route) => {
      if (route.name && !constantRoutes.find((r) => r.name === route.name)) {
        // 删除动态路由
        router.removeRoute(route.name);
      }
    });

    loadRoutesFlag.value = false;
    menuRoutes.value = [];
  };

  return {
    menuRoutes,
    loadRoutesFlag,
    generateRoutes,
    resetRouter,
  };
});


/**
 * 转换路由数据为组件
 */
const transformRoutes = (menuRoutes: RouteVO[]) => {
  const asyncRoutes: RouteRecordRaw[] = [];
  menuRoutes.forEach((route) => {
    const tmpRoute = { ...route } as RouteRecordRaw;

    if (tmpRoute.component?.toString() == "Layout") {
      // Layout 组件
      tmpRoute.component = Layout;
    } else {
      // 根据组件路径动态加载组件
      const component = modules[`@/views/${tmpRoute.component}.vue`];
      if (component) {
        tmpRoute.component = component;
      } else {
        tmpRoute.component = modules["@/views/error/404.vue"];
      }
    }

    if (tmpRoute.children) {
      tmpRoute.children = transformRoutes(route.children);
    }

    asyncRoutes.push(tmpRoute);
  });

  return asyncRoutes;
};
